package com.xmh.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

@SuppressWarnings("deprecation")
public class ActionUtil {
	private final static HttpClient CLIENT = new DefaultHttpClient();

	private final static ThreadLocal<SimpleDateFormat> SIMPLEDATEFORMAT_THREADLOCAL = new ThreadLocal<>();

	private final static String PATTERN = "yyyy-MM-dd HH:mm:ss";

	private final static Logger logger = Logger.getLogger(ActionUtil.class);
	

	public static final SimpleDateFormat getSimpleDateFormat() {
		SimpleDateFormat sdFormat = SIMPLEDATEFORMAT_THREADLOCAL.get();

		if (sdFormat == null) {
			sdFormat = new SimpleDateFormat(PATTERN);
			SIMPLEDATEFORMAT_THREADLOCAL.set(sdFormat);
		}
		return sdFormat;
	}

	public static String doReflectCallPost(String className, String methodName, Map<String, Object> params) {
		String json = mapToJSON(params);

		logger.debug("参数json为：   " + json);

		Map<String, Object> map = new HashMap<>();

		map.put("methodName", methodName);
		map.put("className", className);
		map.put("params", json);

		return doPost2(PropertiesUtil.getWebServerUrl(), map);
//		return doPost(PropertiesUtil.getWebServerUrl(), map);
	}

	public static String mapToJSON(Map<String, Object> params) {
		Set<String> keySet = params.keySet();

		int i = 0;

		int size = keySet.size();

		StringBuffer sBuffer = new StringBuffer();

		for (String key : keySet) {
			Object object = params.get(key);

			String value = null;

			if (object == null) {

			} else if (object instanceof String) {
				String val = String.valueOf(object);

				String replace = val.replace("\"", "\\\"");
				replace = replace.replace("\n", "");
				replace = replace.replace("\t", "");

				value = "\"" + replace + "\"";
			} else if (object instanceof Collection) {
				value = collectionToJSON((Collection<?>) object);
			} else if (object instanceof Date) {
				String format = getSimpleDateFormat().format((Date) object);

				value = "\"" + format + "\"";
			} else {
				value = String.valueOf(object);
			}

			if (size == 1) {
				sBuffer.append("{\"");
				sBuffer.append(key);
				sBuffer.append("\":");
				sBuffer.append(value);
				sBuffer.append("}");
			} else if (i == 0) {
				sBuffer.append("{\"");
				sBuffer.append(key);
				sBuffer.append("\":");
				sBuffer.append(value);
				sBuffer.append(",");
			} else if (i == size - 1) {
				sBuffer.append("\"");
				sBuffer.append(key);
				sBuffer.append("\":");
				sBuffer.append(value);
				sBuffer.append("}");
			} else {
				sBuffer.append("\"");
				sBuffer.append(key);
				sBuffer.append("\":");
				sBuffer.append(value);
				sBuffer.append(",");
			}
			i++;
		}
		return sBuffer.toString();
	}

	@SuppressWarnings("unchecked")
	public static String collectionToJSON(Collection<?> collection) {
		int i = 0;

		int size = collection.size();

		StringBuffer sBuffer = new StringBuffer();

		for (Object obj : collection) {

			String value = null;

			if (obj == null) {
				value = null;
			} else if (obj instanceof String) {
				String val = String.valueOf(obj);

				String replace = val.replace("\"", "\\\"");
				replace = replace.replace("\n", "");
				replace = replace.replace("\t", "");
				replace = replace.replace(" ", "");

				value = "\"" + replace + "\"";
			} else if (obj instanceof Map) {
				value = mapToJSON((Map<String, Object>) obj);
			} else if (obj instanceof Date) {
				String format = getSimpleDateFormat().format((Date) obj);

				value = "\"" + format + "\"";
			} else {
				value = String.valueOf(obj);
			}

			if (i == 0) {
				sBuffer.append("[");
				sBuffer.append(value);
				sBuffer.append(",");
			} else if (i == size - 1) {
				sBuffer.append(value);
				sBuffer.append("]");
			} else {
				sBuffer.append(value);
				sBuffer.append(",");
			}
			i++;
		}
		return sBuffer.toString();
	}

	/**
	 * post请求(用于key-value格式的参数)
	 * 
	 * @param url
	 * @param params
	 * @return
	 */
	public static String doPost(String url, Map<String, Object> params) {
		BufferedReader in = null;
		InputStreamReader in2 = null;
		InputStream contentIS = null;

		logger.debug("---------开始发送");

		try {
			// 定义HttpClient
			// 实例化HTTP方法
			HttpPost request = new HttpPost();

			request.setURI(new URI(url));

			// 设置参数
			List<NameValuePair> nvps = new ArrayList<NameValuePair>();
			for (String name : params.keySet()) {
				String value = String.valueOf(params.get(name));
				nvps.add(new BasicNameValuePair(name, value));

				logger.debug("---发送参数 ： " + name + "   value:   " + value);
			}

			request.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));

			HttpResponse response = CLIENT.execute(request);
			int code = response.getStatusLine().getStatusCode();
			if (code == 200) { // 请求成功
				contentIS = response.getEntity().getContent();

				in2 = new InputStreamReader(contentIS, "utf-8");

				in = new BufferedReader(in2);

				StringBuffer sb = new StringBuffer("");

				String line = "";

				String NL = System.getProperty("line.separator");

				while ((line = in.readLine()) != null) {
					sb.append(line + NL);
				}

				in.close();

				String requets = sb.toString();

				logger.debug("--------返回结果：" + requets);

				return requets;
			} else {
				logger.debug("状态码：" + code);
				return null;
			}
		} catch (Exception e) {
			logger.error("请求失败", e);
			return null;
		} finally {
			try {
				if (contentIS != null) {
					contentIS.close();
				}
				if (in2 != null) {
					in2.close();
				}
				if (in != null) {
					in.close();
				}
				// 关闭连接,释放资源
				// CLIENT.getConnectionManager().shutdown();
			} catch (IOException e) {
				logger.error("关闭流失败", e);
			}

		}
	}

	public static String doPost2(String url, Map<String, Object> paramMap) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse httpResponse = null;
		String result = null;
		// 创建httpClient实例
		httpClient = HttpClients.createDefault();
		// 创建httpPost远程连接实例
		HttpPost httpPost = new HttpPost(url);
		// 配置请求参数实例
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(60000)// 设置连接主机服务超时时间
				.setConnectionRequestTimeout(60000)// 设置连接请求超时时间
				.setSocketTimeout(60000)// 设置读取数据连接超时时间
				.build();
		// 为httpPost实例设置配置
		httpPost.setConfig(requestConfig);
		// 设置请求头
		httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
//		httpPost.addHeader("Content-Type", "application/json")		// 封装post请求参数
//		httpPost.setEntity(new StringEntity("你的json串"));    

		if (null != paramMap && paramMap.size() > 0) {
			List<NameValuePair> nvps = new ArrayList<NameValuePair>();
			// 通过map集成entrySet方法获取entity
			Set<Entry<String, Object>> entrySet = paramMap.entrySet();
			// 循环遍历，获取迭代器
			Iterator<Entry<String, Object>> iterator = entrySet.iterator();
			while (iterator.hasNext()) {
				Entry<String, Object> mapEntry = iterator.next();
				nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString()));
			}

			// 为httpPost设置封装好的请求参数
			try {
				httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
			} catch (UnsupportedEncodingException e) {
				logger.error("请求出现异常", e);
				return null;
			}
		}
		try {
			// httpClient对象执行post请求,并返回响应参数对象
			httpResponse = httpClient.execute(httpPost);
			
//			// 从响应对象中获取响应内容
			HttpEntity entity = httpResponse.getEntity();
			result = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			logger.error("请求出现异常", e);
		} finally {
			try {
				// 关闭资源
				if (null != httpResponse) {
					httpResponse.close();
				}
				if (null != httpClient) {
					httpClient.close();
				}
			} catch (IOException e) {
				logger.error("关闭httpClient的时候出现异常", e);
			}
		}
		return result;
	}

}
